#define is_guest_l1_slot(_s) (1)
#define is_guest_l2_slot(_t,_s) ((_s) < L2_PAGETABLE_FIRST_XEN_SLOT)
+/*
+ * PTE pfn and flags:
+ * 20-bit pfn = (pte[31:12])
+ * 12-bit flags = (pte[11:0])
+ */
+
+/* Extract flags into 12-bit integer, or turn 12-bit flags into a pte mask. */
#define get_pte_flags(x) ((int)(x) & 0xFFF)
#define put_pte_flags(x) ((intpte_t)(x))
#define L3_PAGETABLE_ENTRIES 4
#define ROOT_PAGETABLE_ENTRIES L3_PAGETABLE_ENTRIES
-#define PADDR_BITS 52
+/*
+ * Architecturally, physical addresses may be up to 52 bits. However, the
+ * page-frame number (pfn) of a 52-bit address will not fit into a 32-bit
+ * word. Instead we treat bits 44-51 of a pte as flag bits which are never
+ * allowed to be set by a guest kernel. This 'limits' us to addressing 16TB
+ * of physical memory on a 32-bit PAE system.
+ */
+#define PADDR_BITS 44
#define PADDR_MASK ((1ULL << PADDR_BITS)-1)
#ifndef __ASSEMBLY__
((_s) < (L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1))))
#define is_guest_l3_slot(_s) (1)
-#define get_pte_flags(x) ((int)((x) >> 40) | ((int)(x) & 0xFFF))
-#define put_pte_flags(x) ((((intpte_t)((x) & ~0xFFF)) << 40) | ((x) & 0xFFF))
+/*
+ * PTE pfn and flags:
+ * 32-bit pfn = (pte[43:12])
+ * 32-bit flags = (pte[63:44],pte[11:0])
+ */
+
+/* Extract flags into 32-bit integer, or turn 32-bit flags into a pte mask. */
+#define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF))
+#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))
#define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
#define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */
#define __PAGE_OFFSET (0xFFFF830000000000)
-/* These are page-table limitations. Current CPUs support only 40-bit phys. */
+/* These are architectural limits. Current CPUs support only 40-bit phys. */
#define PADDR_BITS 52
#define VADDR_BITS 48
#define PADDR_MASK ((1UL << PADDR_BITS)-1)
#define root_create_phys l4e_create_phys
#define PGT_root_page_table PGT_l4_page_table
-#define get_pte_flags(x) ((int)((x) >> 40) | ((int)(x) & 0xFFF))
-#define put_pte_flags(x) ((((intpte_t)((x) & ~0xFFF)) << 40) | ((x) & 0xFFF))
+/*
+ * PTE pfn and flags:
+ * 40-bit pfn = (pte[51:12])
+ * 24-bit flags = (pte[63:52],pte[11:0])
+ */
+
+/* Extract flags into 24-bit integer, or turn 24-bit flags into a pte mask. */
+#define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF))
+#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))
-#define _PAGE_NX (cpu_has_nx ? (1U<<23) : 0U)
+/* Bit 23 of a 24-bit flag mask. This corresponds to bit 63 of a pte.*/
+#define _PAGE_NX (cpu_has_nx ? (1U<<23) : 0U)
#define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
#define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */